package org.testis.webautomationmodule.ui.objects;

import org.testis.data.AtofModuleConstants;
import org.testis.logging.AtofLogLevel;
import org.testis.webautomationmodule.ui.UIElementNotFoundException;
import org.testis.webautomationmodule.ui.UIFormFieldDecorator;
import org.testis.webautomationmodule.ui.UIObjectCreator;
import org.testis.webautomationmodule.ui.WebAutomationDecorator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 *
 * @author nurhat
 */
public class UIDynamicObject extends UIFormFieldDecorator {

    private String m_type;
    private String[] m_parArr;

    public UIDynamicObject(String id,
            String type,
            String value) {
        super(id);
        setValue(value);
        setType(type);
        m_parArr = getValue().split(
                AtofModuleConstants.DYNAMIC_OBJECT_SPLIT_STR);
    }

    @Override
    protected boolean setBehavior() {
        putLog("Operating UIDynamicObject with id="
                + getId()
                + " type=" + getType() + " value=" + getValue());
        WebAutomationDecorator deco = getDynamicObject();
        return deco.operate();
    }

    @Override
    public boolean verifyBehavior() {
        putLog("Verifying UIDynamicObject with id="
                + getId()
                + " type=" + getType() + " value=" + getValue());
        WebAutomationDecorator deco = getDynamicObject();
        boolean result = deco.verify();
        if (deco instanceof UIFormFieldDecorator) {
            setValue(((UIFormFieldDecorator) deco).getValue());
        }
        return result;
    }

    @Override
    public boolean getBehavior() {
        putLog("Getting value of UIDynamicObject with id="
                + getId()
                + " type=" + getType());
        WebAutomationDecorator deco = getDynamicObject();
        boolean result = deco.get();
        if (deco instanceof UIFormFieldDecorator) {
            setValue(((UIFormFieldDecorator) deco).getValue());
        }
        return result;

    }

    public String getType() {
        return m_type;
    }

    public void setType(String type) {
        this.m_type = type;
    }

    private WebAutomationDecorator getDynamicObject() throws RuntimeException {
        Object[] constArgs = null;
        if (setObjectId()) {
            try {
                String valueToSet = "";
                if (m_parArr.length > 2) {
                    valueToSet = m_parArr[2];
                } else {
                    valueToSet = m_parArr[1];
                }
                if (!m_type.equals("UILabel")) {
                    constArgs = new Object[2];
                } else {
                    constArgs = new Object[3];
                    constArgs[2] = true;
                }
                constArgs[0] = getId();
                constArgs[1] = valueToSet;
                UIObjectCreator fac =
                        new UIObjectCreator();
                WebAutomationDecorator deco =
                        fac.createUIObject(m_type,
                        constArgs,
                        getMessageId());
                deco.setWebAutomationImpl(getWebAutomationImpl());
                deco.setAbstractId(getAbstractId());
                return deco;
            } catch (Exception ex) {
                putLog("Could not create object  for UIDynamicObject. id="
                        + getId()
                        + " type=" + getType() + " value=" + getValue(),
                        AtofLogLevel.ERROR);
                throw new UIElementNotFoundException("Could not find object  for UIDynamicObject. id="
                        + getId() + " type="
                        + getType()
                        + " value="
                        + getValue() + "..Exception:"
                        + ex.getMessage());
            }

        }
        putLog("Could not find object id for UIDynamicObject. id=" + getId()
                + " type=" + getType() + " value=" + getValue(),
                AtofLogLevel.ERROR);

        throw new UIElementNotFoundException("Could not find object id for UIDynamicObject. id="
                + getId() + " type=" + getType()
                + " value="
                + getValue());
    }

    private boolean setObjectId() {
        if (m_parArr.length < 2) {
            return false;
        }
        String locatorId = getObjectId();
        if (locatorId != null) {
            setId(locatorId);
            return true;
        }
        return false;
    }

    private String getObjectId() {
        String idList = getWebAutomationImpl().getEval(
                "function findDynamicElement(objId){ "
                + " var tags = selenium.browserbot.getDocument().getElementsByTagName('*'); "
                + " var ids='';"
                + " for (var i=0; i< tags.length; i++) {"
                + "    if(tags[i].id){"
                + "      if (tags[i].id.startsWith(objId))"
                + "       { if(ids==''){ ids=tags[i].id; }"
                + "         else{ids=ids+'" + AtofModuleConstants.PARAM_SEP_STR + "'+ tags[i].id;} "
                + "       }"
                + "    }"
                + "  } "
                + "  return ids"
                + "}; "
                + "eval('findDynamicElement(\"" + m_parArr[0] + "\")');");
        if (!idList.isEmpty()) {
            String[] ids = idList.split(AtofModuleConstants.PARAM_SEP_SPLIT_STR);
            String locatorId = "";
            String compareVal = m_parArr[1].trim();
            String compareValUpper = m_parArr[1].trim();
            boolean isRegex = false;
            Pattern pattern = null;
            if (compareVal.startsWith(AtofModuleConstants.REGEX_DEFINITION_STR)) {
                isRegex = true;
                pattern = Pattern.compile(compareVal.replace(AtofModuleConstants.REGEX_DEFINITION_STR, ""));
            }
            for (int i = 0; i < ids.length; i++) {
                String elementText = "";
                try {
                    elementText = getWebAutomationImpl().getText(ids[i]);
                } catch (RuntimeException ex) {
                } catch (Exception ex) {
                }
                try {
                    if (elementText.isEmpty()) {
                        elementText = getWebAutomationImpl().getValue(ids[i]);
                    }
                } catch (RuntimeException ex) {
                } catch (Exception ex) {
                }
                if (!isRegex) {
                    if (elementText.equals(compareVal)) {
                        locatorId = ids[i];
                        break;
                    } else if (elementText.toUpperCase().equals(compareValUpper)) {
                        locatorId = ids[i];
                        break;
                    }
                } else {
                    Matcher matcher = pattern.matcher(elementText);
                    if (matcher.matches()) {
                        locatorId = ids[i];
                        break;
                    }
                }
            }

            if (!locatorId.isEmpty()) {
                String locatorIdEnd = locatorId.replace(m_parArr[0],
                        "");
                String id = m_id + locatorIdEnd;
                if (getWebAutomationImpl().isElementPresent(id)) {
                    return id;
                } else {
                    String[] indices = locatorIdEnd.split("_");
                    if (indices.length > 2) {
                        id = m_id + "_" + indices[1];
                        if (getWebAutomationImpl().isElementPresent(id)) {
                            return id;
                        }
                        id = m_id + indices[1];
                        if (getWebAutomationImpl().isElementPresent(id)) {
                            return id;
                        }
                    }
                }
                return m_id + locatorIdEnd;

            }
        }
        return null;

    }
}
